home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
cit.arc
/
NET.C
< prev
next >
Wrap
C/C++ Source or Header
|
1986-01-16
|
41KB
|
1,423 lines
/************************************************************************/
/* net.c */
/* */
/* Networking functions. */
/************************************************************************/
/************************************************************************/
/* history */
/* */
/* 85Dec29 HAW File created. This will be .LIB rather than .OBJ. */
/* 85Oct28 HAW Start adding file transfers. */
/* 85Oct27 JLS New networking scheme -- transactional. */
/* 85Oct17 HAW 2400 baud support. */
/* 85Sep18 HAW Put 'system busy' message out (netstuff) to callers. */
/* 85Aug31 HAW Add "outgoing" and "baud" feature to writeNet(). */
/* 85Aug28 HAW Fix minor bug in scheduler, allow for incoming. */
/* 85Aug24 HAW Fix inMail() to allow for netMail to 'Sysop'. */
/* 85Jul22 JLS Major changes to networker. */
/* 85Jun05 HAW Add networking code to file MISC.C */
/************************************************************************/
#include "ctdl.h"
/************************************************************************/
/* contents */
/* */
/************************************************************************/
/************************************************************************/
/* External variable declarations in NET.C */
/************************************************************************/
unsigned char sectBuf[SECTSIZE + 5];
int counter;
int FinHour, FinMinute;
label normed, callerName, callerId;
char searchNet(), normId(), getNetMessage();
char getLong(), callOut();
unsigned char inp();
#define needToCall(i) (netTab[i].ntflags.in_use == TRUE &&\
(netTab[i].ntflags.normal_mail == TRUE || netTab[i].ntflags.room_files == TRUE))
#define HANGUP 0
#define S_M_N 1
#define INTERVALS 8 /* Half second intervals */
#define minimum(x,y) ((x) < (y) ? (x) : (y))
/************************************************************************/
/* External variable definitions for NET.C */
/************************************************************************/
extern struct config cfg; /* Lots an lots of variables */
extern struct logBuffer logBuf; /* Person buffer */
extern struct aRoom roomBuf; /* Room buffer */
extern struct rTable roomTab[];
extern struct msgB msgBuf,tempMess;
extern struct netBuffer netBuf;
extern struct netTable *netTab;
extern FILE *upfd;
extern int thisNet;
extern char loggedIn; /* Is we logged in? */
extern char outFlag; /* Output flag */
extern char haveCarrier; /* Do we still got carrier? */
extern unsigned char modStat; /* Needed so we don't die */
extern char usingWCprotocol;/* WC flag */
extern char WCError;
extern int thisRoom;
extern int thisLog;
/************************************************************************/
/* External function definitions for NET.C */
/************************************************************************/
FILE *fopen();
char *realloc();
/************************************************************************/
/* called() We've been called, so let's handle it */
/************************************************************************/
called()
{
char processMail = FALSE;
label tempNm;
int count;
struct cmd_data cmds;
for (count = 0; count < 4; count++)
cmds.fields[count][0] = 0;
printf("Caller detected\n");
if (!called_stabilize()) return ;
printf("Caller stabilized\n");
getId();
if (!haveCarrier) return;
do {
getNextCommand(&cmds);
switch (cmds.command) {
case HANGUP: break;
case NORMAL_MAIL: getMail(&cmds);
processMail = TRUE; break;
case R_FILE_REQ: netFileReq(&cmds); break;
default: sPrintf(tempNm, "'%d' unknown.", cmds.command);
reply(BAD, tempNm); break;
}
} while (gotCarrier() && cmds.command != HANGUP);
printf("Networking finished, terminating call from %s\n",callerName);
modStat = haveCarrier = FALSE;
interpret(cfg.pHangUp);
if (processMail) readMail();
}
/************************************************************************/
/* getId() Gets nodeId and nodeName from caller. */
/************************************************************************/
getId()
{
int increment();
int i;
char *secRunner;
if (!haveCarrier) return;
counter = 0;
readFile(increment);
if (!gotCarrier()) return modStat = haveCarrier = FALSE;
strCpy(callerId, sectBuf);
secRunner = sectBuf;
while (*secRunner != 0) secRunner++;
secRunner++;
strCpy(callerName, secRunner);
normId(callerId, normed);
if (!searchNet(normed)) {
sPrintf(msgBuf.mbtext, "New caller: %s (%s)", callerName, callerId);
aideMessage(FALSE);
}
printf("Call from %s (%s)\n", callerName, callerId);
}
/************************************************************************/
/* getNextCommand() Gets next command from caller */
/************************************************************************/
getNextCommand(cmds)
struct cmd_data *cmds;
{
int increment();
counter = 0;
readFile(increment);
if (!gotCarrier()) return modStat = haveCarrier = FALSE;
grabCommand(cmds, sectBuf);
}
/************************************************************************/
/* grabCommand() Pulls network cmds out of specified buffer */
/************************************************************************/
grabCommand(cmds, sect)
char *sect;
struct cmd_data *cmds;
{
int fcount = 0;
cmds->command = sect[0];
sect++;
while (sect[0] > 0 && fcount < 4) {
strCpy(cmds->fields[fcount++], sect);
while (*sect != 0) sect++;
sect++;
}
}
/************************************************************************/
/* reply() Replies to caller */
/************************************************************************/
reply(state, reason)
char state;
char *reason;
{
if (!doWC(STARTUP)) {
no_good("Couldn't send reply to %s!", TRUE);
modStat = haveCarrier = FALSE;
interpret(cfg.pHangUp);
return;
}
if (cfg.debug) printf("Replying %s\n", (state == BAD) ? "BAD:" : "GOOD");
sendWCChar(state);
if (state == BAD) {
mWCprintf("%s", reason);
if (cfg.debug) printf("%s", reason);
}
sendWCChar(0);
doWC(FINISH);
}
/************************************************************************/
/* getMail() Grabs mail from caller */
/************************************************************************/
getMail(cmds)
struct cmd_data *cmds;
{
label tempNm;
int putFLChar();
printf("Receiving mail from %s\n", callerName);
reply(GOOD, "");
strCpy(tempNm, "a:tempmail.$$$");
tempNm[0] = cfg.netDisk + 'a';
if ((upfd = fopen(tempNm, "wrb")) == NULL) {
crashout("Couldn't create networker temporary file!");
}
readFile(putFLChar);
fclose(upfd);
}
/************************************************************************/
/* netFileReq() Handles request for file transfer */
/************************************************************************/
netFileReq(cmds)
struct cmd_data *cmds;
{
int roomSlot;
int data;
char reason[50];
FILE *fd;
if (cfg.debug) printf("\nRequest for %s from %s\n", cmds->fields[0],
cmds->fields[1]);
if ((roomSlot = roomExists(cmds->fields[0])) == ERROR ||
roomTab[roomSlot].rtflags.MSDOSDIR != 1) {
sPrintf(reason, "Room %s does not exist.", cmds->fields[0]);
reply(BAD, reason);
return;
}
getRoom(roomSlot);
if (!setSpace(roomBuf.rbdisk, roomBuf.rbdirname)) {
sPrintf(reason, "Couldn't open directory for %s.", cmds->fields[0]);
reply(BAD, reason);
return;
}
if ((fd = fopen(cmds->fields[1], "rb")) == NULL) {
sPrintf(reason, "There is no '%s' in %s.", cmds->fields[1],
cmds->fields[0]);
reply(BAD, reason);
if (strLen(roomBuf.rbdirname) != 0) setSpace(roomBuf.rbdisk, "..");
setSpace(cfg.homeDisk, "");
return;
}
reply(GOOD, "");
if (doWC(STARTUP)) {
while ((data = fgetc(fd)) != EOF && data != -1)
if (!sendWCChar(data)) break;
doWC(FINISH);
}
fclose(fd);
if (strLen(roomBuf.rbdirname) != 0) setSpace(roomBuf.rbdisk, "..");
setSpace(cfg.homeDisk, "");
sPrintf(msgBuf.mbtext,
"File \"%s\" downloaded from %s during networking by %s.",
cmds->fields[1], roomBuf.rbname, callerName);
aideMessage(FALSE);
}
/************************************************************************/
/* increment() */
/************************************************************************/
increment(c)
unsigned char c;
{
sectBuf[counter++] = c;
if (counter > SECTSIZE+2) {
interpret(cfg.pHangUp);
modStat = haveCarrier = FALSE;
}
return TRUE;
}
/************************************************************************/
/* normId() Normalizes a node id. */
/************************************************************************/
char normId(source, dest)
label source, dest;
{
while (!isalpha(*source) && *source)
source++;
if (!*source) return FALSE;
*dest++ = toUpper(*source++);
while (!isalpha(*source) && *source)
source++;
if (!*source) return FALSE;
*dest++ = toUpper(*source++);
while (*source) {
if (isdigit(*source))
*dest++ = *source;
source++;
}
*dest = '\0';
return TRUE;
}
/************************************************************************/
/* called_stabilize() Attempts to stabilize communication on */
/* receiver end. */
/************************************************************************/
called_stabilize()
{
int Time = 0, f, baudRunner = 0;
char noGood, notFinished, notDone = TRUE;
char laterMessage[100];
pause(100); /* Pause a full second */
while (notDone) {
noGood = TRUE;
if (cfg.search_baud) {
while (MIReady()) inp(); /* Clear garbage */
while (gotCarrier() && noGood && Time < 20) {
Time++;
for (notFinished = TRUE; noGood && gotCarrier() && notFinished;){
interpret(cfg.pBauds[baudRunner]);
noGood = check_for_init();
if (cfg.debug) printf(".\n");
notFinished = !(baudRunner == cfg.sysBaud);
baudRunner = (baudRunner + 1) % (cfg.sysBaud + 1);
}
}
}
else {
interpret(cfg.pBauds[interpret(cfg.pCheckBaud)]);
for (; gotCarrier() && Time < 20 && noGood; Time++) {
noGood = check_for_init();
if (cfg.debug) printf(".\n");
}
if (cfg.debug) printf("\n");
}
if (!gotCarrier()) {
modStat = haveCarrier = FALSE;
printf("Lost carrier\n");
return FALSE;
}
if (noGood && Time == 20) {
outFlag = IMPERVIOUS;
sPrintf(laterMessage,
"System will be in network mode for another %d minutes; please call back.\n",
timeLeft());
if (cfg.search_baud) {
for (baudRunner = cfg.sysBaud; baudRunner > -1; baudRunner--) {
interpret(cfg.pBauds[baudRunner]);
mPrintf(laterMessage);
}
}
else
mPrintf(laterMessage);
interpret(cfg.pHangUp);
notDone = modStat = haveCarrier = FALSE;
outFlag = OUTOK;
}
else {
if (cfg.debug) printf("&");
outMod(~7 );
outMod(~13);
outMod(~69);
f = receive(2);
if (f == ACK)
return TRUE ;
else if (cfg.debug) printf("%d ", f);
if (!gotCarrier())
modStat = haveCarrier = notDone = FALSE;
}
}
if (!gotCarrier())
modStat = haveCarrier = FALSE;
return FALSE;
}
/************************************************************************/
/* check_for_init() Looks for networking initialization sequence */
/************************************************************************/
check_for_init()
{
#ifdef OLD_STYLE
int i, j, x;
for (i = 0; i < INTERVALS && !MIReady(); i++)
for (j = 0; j < 250 && !MIReady(); j++)
shortPause();
if (MIReady()) {
if ((x = inp()) != 7) {
if (cfg.debug) printf("1 was %d\n", x);
return TRUE;
}
x = receive(2);
if (x != 13) {
if (cfg.debug) printf("1 was 7, 2 was %d\n", x);
return TRUE;
}
x = receive(2);
if (x != 69) {
if (cfg.debug) printf("1 was 7, 2 was 13, 3 was %d\n", x);
return TRUE;
}
if (cfg.debug) printf("SUCCESS\n");
return FALSE;
}
return TRUE;
#else
int count, timeOut;
unsigned char thisVal, lastVal;
lastVal = 0;
timeOut = (INTERVALS / 2) * (500);
for (count = 0; count < timeOut; count++) {
if (MIReady()) {
thisVal = inp();
if (cfg.debug) printf("%d ", thisVal);
switch (thisVal) {
case 7: lastVal = 7; break;
case 13:
if (lastVal == 7) lastVal = 13;
else lastVal = 0;
break;
case 69:
if (lastVal == 13) return FALSE;
else lastVal = 0;
break;
default:
lastVal = 0;
}
}
else shortPause();
}
return TRUE;
}
/************************************************************************/
/* searchNet() Searches net for the given Id. */
/************************************************************************/
char searchNet(forId)
char *forId;
{
int rover;
label temp;
for (rover = 0; rover < cfg.netSize; rover++) {
if (netTab[rover].ntflags.in_use &&
hash(forId) == netTab[rover].ntidhash) {
getNet(rover);
normId(netBuf.netId, temp);
if (strCmpU(temp, forId) == SAMESTRING)
return TRUE;
}
}
return FALSE;
}
/************************************************************************/
/* readMail() Integrates mail into the data base */
/************************************************************************/
readMail()
{
label tempNm;
strCpy(tempNm, "a:tempmail.$$$");
tempNm[0] = cfg.netDisk + 'a';
if ((upfd = fopen(tempNm, "rb")) == NULL) {
no_good("Couldn't open tempmail file from %s.", TRUE);
return;
}
getRoom(MAILROOM);
while (getNetMessage()) {
if (strCmpU(cfg.nodeId + cfg.codeBuf, tempMess.mborig) != SAMESTRING)
inMail();
}
fclose(upfd);
unlink(tempNm);
}
/************************************************************************/
/* getNetMessage() gets a message from a global file */
/************************************************************************/
char getNetMessage()
{
int marker, c;
marker = 0;
while (marker != 'M') {
while ((marker = getc(upfd)) != -1 && marker == ' ')
;
if (marker == -1) {
return FALSE;
}
switch (marker) {
case 'A':
getNetStr(tempMess.mbauth);
break;
case 'D':
getNetStr(tempMess.mbdate);
break;
case 'N':
getNetStr(tempMess.mboname);
break;
case 'O':
getNetStr(tempMess.mborig);
break;
case 'R':
getNetStr(tempMess.mbroom);
break;
case 'S':
getNetStr(tempMess.mbsrcId);
break;
case 'T':
getNetStr(tempMess.mbto);
break;
case 'C':
getNetStr(tempMess.mbtime);
break;
default:
if (marker != 'M')
while ((c = getc(upfd)) != -1 && c != '\0')
;
break;
}
}
getNetStr(tempMess.mbtext);
return TRUE;
}
/************************************************************************/
/* getNetStr() gets a string from networked message */
/************************************************************************/
getNetStr(place)
char *place;
{
int i, c;
i = 0;
do {
c = getc(upfd);
if (c == '\r') c = '\n';
place[i++] = c;
} while (c != -1 && c != '\0');
}
/************************************************************************/
/* inMail() integrates mail into database */
/************************************************************************/
inMail()
{
int logNo;
struct logBuffer lBuf;
if (!tempMess.mbto[0]) return ;
logNo = findPerson(tempMess.mbto, &lBuf);
strCpy(msgBuf.mbto, tempMess.mbto);
if (logNo == ERROR && hash(tempMess.mbto) != hash("Sysop")) {
printf("Mail to '%s' cannot be delivered.\n", tempMess.mbto);
return;
}
else printf("Delivering mail to '%s'\n", tempMess.mbto);
strCpy(msgBuf.mbto, lBuf.lbname);
strCpy(tempMess.mbto, lBuf.lbname);
putNetMessage();
noteMessage(&lBuf, logNo);
}
/************************************************************************/
/* caller() we've called and got carrier, so let's goferit */
/************************************************************************/
caller()
{
printf("Carrier detected\n");
caller_stabilize();
if (!haveCarrier) return ; /* Abort */
printf("Have stabilized call with receiver\n");
sendId();
if (netBuf.nbflags.normal_mail)
sendMail();
if (netBuf.nbflags.room_files)
askFiles();
sendHangUp();
while (gotCarrier()) ;
printf("\nCall to %s finished successfully\n", netBuf.netName);
modStat = haveCarrier = FALSE;
putNet(thisNet);
}
/************************************************************************/
/* caller_stabilize() Tries to stabilize the call -- */
/* baud is already set */
/************************************************************************/
caller_stabilize()
{
int Time, i, j;
int x1, x2, x3;
pause(200); /* Pause a full 2 seconds */
while (MIReady()) inp(); /* Clear garbage */
for (Time = 0; Time < 20 && gotCarrier(); Time++) {
if (cfg.debug) printf(".");
outMod(7);
pause(10);
outMod(13);
pause(10);
outMod(69);
for (j = 0; j < INTERVALS && !MIReady(); j++)
for (i = 0; i < 250 && !MIReady(); i++)
shortPause();
if (MIReady()) {
x1 = receive(2);
x2 = receive(2);
if (x2 != ERROR) x3 = receive(2);
if (x1 == 248 &&
x2 == 242 &&
x3 == 186) {
outMod(ACK);
if (cfg.debug) printf("ACKing, Call stabilized\n");
return;
}
else if (cfg.debug) printf("%d %d %d\n", x1, x2, x3);
}
}
printf("Call not stabilized\n");
modStat = haveCarrier = FALSE;
interpret(cfg.pHangUp);
}
/************************************************************************/
/* sendId() Sends ID to the receiver */
/************************************************************************/
sendId()
{
char *reason;
char message[40];
if (!haveCarrier) return;
if (!doWC(STARTUP)) {
no_good("Couldn't transfer ID to %s!", TRUE);
modStat = haveCarrier = FALSE;
interpret(cfg.pHangUp);
return;
}
mWCprintf("%s", cfg.codeBuf + cfg.nodeId );
mWCprintf("%s", cfg.codeBuf + cfg.nodeName);
if (WCError) {
if (!gotCarrier()) {
modStat = haveCarrier = FALSE;
reason = "carrier loss";
}
else reason = "WC abort: 10 errors or CANCEL";
doWC(FINISH);
strCpy(message, "Couldn't transfer ID to %s! ");
strCat(message, reason);
no_good(message, TRUE);
return;
}
doWC(FINISH);
}
/************************************************************************/
/* sendMail() send normal mail to receiver */
/************************************************************************/
sendMail()
{
struct cmd_data cmds;
int i, nor_mail;
char *reason, message[50];
if (!haveCarrier) return;
printf("Sending normal mail\n");
cmds.command = NORMAL_MAIL;
for (i = 0; i < 4; i++)
cmds.fields[i][0] = 0;
if (!sendNetCommand(&cmds, "Couldn't send Normal Mail command to %s!"))
return;
if (!doWC(STARTUP)) {
no_good("Couldn't transfer ID to %s!", TRUE);
modStat = haveCarrier = FALSE;
interpret(cfg.pHangUp);
return;
}
nor_mail = s_m_n(); /* Send normal mail */
if (WCError) {
if (!gotCarrier()) {
modStat = haveCarrier = FALSE;
reason = "carrier loss";
}
else reason = "WC abort: 10 errors or CANCEL";
doWC(FINISH);
strCpy(message, "Couldn't transfer ID to %s! ");
strCat(message, reason);
no_good(message, TRUE);
return;
}
else {
printf("\nSuccessful transfer of %d messages\n", nor_mail);
netBuf.nbflags.normal_mail = FALSE;
}
doWC(FINISH);
}
/************************************************************************/
/* askFiles() ask for file(s) from caller */
/************************************************************************/
askFiles()
{
label data;
int putFLChar(), i;
char mess[130], *cd, *gcdir();
FILE *temp;
struct cmd_data cmds;
struct fl_req file_data;
sPrintf(data, "a:%d.rfl", thisNet);
data[0] = cfg.netDisk + 'a';
temp = fopen(data, "rb");
if (temp == NULL) {
no_good("Couldn't open room request file for %s", FALSE);
netBuf.nbflags.room_files = FALSE;
}
else {
while (fread(&file_data, sizeof (file_data), 1, temp) == 1 &&
gotCarrier()){
setSpace(toUpper(file_data.drive) - 'A', "");
cd = gcdir("");
if (chdir(file_data.path) != EOF) {
cmds.command = R_FILE_REQ;
for (i = 2; i < 4; i++)
cmds.fields[i][0] = 0;
strCpy(cmds.fields[0], file_data.room);
strCpy(cmds.fields[1], file_data.roomfile);
if (cfg.debug) printf("Asking for file %s in %s\n", file_data.roomfile,
file_data.room);
if (!sendNetCommand(&cmds, "Couldn't ask for files from %s!")) {
if (cfg.debug) printf("No file reported.\n");
strCpy(mess, "%s reports: ");
strCat(mess, sectBuf + 1);
no_good(mess, FALSE);
}
else {
upfd = fopen(file_data.filename, "wb");
readFile(putFLChar);
fclose(upfd);
}
chdir(cd);
if (cfg.debug) printf("About to call free(cd);\n");
free(cd);
if (cfg.debug) printf("Out of call free(cd);\n");
}
setSpace(cfg.homeDisk, "");
}
fclose(temp);
if (gotCarrier()) {
unlink(data);
netBuf.nbflags.room_files = FALSE;
}
else haveCarrier = modStat = FALSE;
}
}
/************************************************************************/
/* sendNetCommand() Sends a command to the receiver */
/************************************************************************/
sendNetCommand(cmds, error)
struct cmd_data *cmds;
char *error;
{
int count, increment();
if (!doWC(STARTUP)) {
no_good(error, TRUE);
modStat = haveCarrier = FALSE;
interpret(cfg.pHangUp);
return;
}
sendWCChar(cmds->command);
for (count = 0; count < 4; count++)
if (cmds->fields[count][0])
mWCPrintf("%s", cmds->fields[count]);
sendWCChar(0);
doWC(FINISH);
counter = 0;
if (cmds->command == HANGUP) return TRUE;
if (cfg.debug) printf("part 1 finished\n");
readFile(increment);
if (cfg.debug) printf("part 2 finished\n");
if (sectBuf[0] == BAD) return FALSE;
return TRUE;
}
/************************************************************************/
/* sendHangUp() Send hangup command to receiver */
/************************************************************************/
sendHangUp()
{
struct cmd_data cmds;
int i;
cmds.command = HANGUP;
for (i = 0; i < 4; i++)
cmds.fields[i][0] = 0;
sendNetCommand(&cmds, "Couldn't send HANGUP command to %s");
}
/************************************************************************/
/* no_good() does error messages */
/************************************************************************/
no_good(str, hup)
char *str;
char hup;
{
sPrintf(msgBuf.mbtext, str, netBuf.netName);
if (hup) {
interpret(cfg.pHangUp);
modStat = haveCarrier = FALSE;
}
aideMessage(FALSE);
}
/************************************************************************/
/* s_m_n() Send mail normal (non-route mail) */
/************************************************************************/
s_m_n()
{
FILE *ptrs;
char c;
label blah, fn;
ulong id;
int val, messCount = 0;
unsigned location;
sPrintf(fn, "a:%d.ml", thisNet);
fn[0] = cfg.netDisk + 'a';
if ((ptrs = fopen(fn, "rb")) == NULL) {
sPrintf(msgBuf.mbtext, "No mail file to send to %s?", netBuf.netName);
aideMessage(FALSE);
return 0;
}
usingWCprotocol = TRUE;
while (1) {
id = 0l;
if (!getLong(ptrs, &id)) break;
location = fgetc(ptrs) << 8;
location += fgetc(ptrs);
printMessage(location, id, blah);
messCount++;
}
usingWCprotocol = FALSE;
fclose(ptrs);
if (!WCError) {
unlink(fn);
return messCount;
}
printf("\nUnsuccessful transfer of normal mail\n");
return 0;
}
/************************************************************************/
/* getLong() Gets a long from the specified file */
/************************************************************************/
char getLong(fd, l)
FILE *fd;
ulong *l;
{
int val;
char c;
val = fgetc(fd);
if (val == -1) return FALSE;
c = val;
*l += (val << 24);
val = fgetc(fd);
c = val;
*l += (val << 16);
val = fgetc(fd);
c = val;
*l += (val << 8);
val = fgetc(fd);
c = val;
*l += (val);
return TRUE;
}
/************************************************************************/
/* netController() Handles the net stuff */
/************************************************************************/
netController()
{
int x;
int searcher = 0, start, first;
ulong waitTime, count;
loggedIn = FALSE; /* Let's be VERY sure. */
thisLog = -1;
printf("\n---------------In Networking Mode--------------\n");
modStat = haveCarrier = FALSE;
srand(cfg.catChar); /* This should be nicely random */
setTime();
while ((x = timeLeft()) > 0) { /* "Can we say inefficient?" */
waitTime = rand();
while (waitTime > minimum(5, ((x/2)))) waitTime /= 2;
/* for (count = 0; count < waitTime * 6000; count++) { */
for (count = 0; count < waitTime * 6000 && !KBReady(); count++) {
pause(1);
if (gotCarrier()) break;
}
if(KBReady()) getCh();
if (gotCarrier()) {
modStat = haveCarrier = TRUE;
called();
}
if (cfg.netSize != 0) {
start = searcher;
do {
if (needToCall(searcher)) {
if (callOut(searcher))
caller();
for (count = 0; count < 20 && !gotCarrier(); count++)
/* Give the modem a chance to recover */
pause(50);
if (gotCarrier()) {
modStat = haveCarrier = TRUE;
called();
}
}
searcher = (searcher + 1) % cfg.netSize;
} while ((searcher+1) % cfg.netSize != start);
}
}
printf("\n---------------Out of Networking Mode--------------\n");
for (searcher = 0; searcher < cfg.netSize; searcher++)
if (needToCall(searcher)) break;
if (searcher < cfg.netSize) {
sPrintf(msgBuf.mbtext, "The following systems could not be reached: ");
for (searcher = 0, first = 1; searcher < cfg.netSize; searcher++)
if (needToCall(searcher)) {
if (!first) strCat(msgBuf.mbtext,", ");
first = FALSE;
getNet(searcher);
strCat(msgBuf.mbtext, netBuf.netName);
}
strCat(msgBuf.mbtext, ".");
aideMessage(FALSE);
}
interpret(cfg.pInitPort);
modStat = haveCarrier = FALSE;
}
/************************************************************************/
/* setTime() Sets up some global variables for the networker */
/************************************************************************/
setTime()
{
int yr, hr, min, dy;
char *mn;
getdate(&yr, &mn, &dy, &hr, &min);
FinHour = hr + cfg.netLength / 60;
FinMinute = cfg.netLength % 60;
}
/************************************************************************/
/* timeLeft() Does a rough estimate of how much time left */
/************************************************************************/
int timeLeft()
{
int yr, hr, min, dy;
char *mn;
getdate(&yr, &mn, &dy, &hr, &min);
if (hr == FinHour && min > FinMinute) return -1;
if (hr > FinHour) return -1;
return ((FinHour - hr) * 60 + abs(min - FinMinute));
}
/************************************************************************/
/* callOut() Attempts to call some other system. */
/************************************************************************/
char callOut(i)
int i;
{
char call[80], ours[10], theirs[10];
label blip1, blip2;
getNet(i);
printf("Calling %s @ %s\n", netBuf.netName, netBuf.netId);
interpret(cfg.pBauds[minimum(netBuf.baudCode, cfg.sysBaud)]);
strCpy(call, "ATD"); /* Assume SM compatible */
normId(netBuf.netId, blip1);
normId(cfg.codeBuf + cfg.nodeId, blip2);
getArea(blip2, ours);
getArea(blip1, theirs);
strCat(call, cfg.codeBuf + cfg.officeStuff);
if (strCmp(ours, theirs) != SAMESTRING) {
if (!cfg.longHaul)
crashout("Supposed to call long distance when LONG-HAUL is 0?");
strCat(call, "1");
strCat(call, blip1 + 2);
}
else {
strCat(call, blip1 + 5);
}
strCat(call, "\r");
moPuts(call);
for (i = 0; i < 4000; i++) {
pause(1);
if (gotCarrier()) break;
}
if (gotCarrier())
return modStat = haveCarrier = TRUE;
outMod('\r'); /* Take SmartModem out of call mode */
return FALSE;
}
/************************************************************************/
/* moPuts() Put a string out to modem without carr check */
/************************************************************************/
moPuts(s)
char *s;
{
while (*s) {
pause(5);
if (cfg.debug) putchar(*s);
outMod(*s++);
}
}
/************************************************************************/
/* getArea() Gets the area code */
/************************************************************************/
getArea(s1, s2)
char *s1, *s2;
{
int i = 0;
while (i < 3) {
if (isdigit(*s1))
s2[i++] = *s1;
s1++;
}
s2[i] = 0;
}
/************************************************************************/
/* netMessage() Send message via net */
/************************************************************************/
netMessage()
{
char notDone = TRUE;
label sys, ourCode, theirCode;
if (!cfg.netParticipant) {
mPrintf("This Citadel is not participating in the net.\n ");
return;
}
if (thisRoom != MAILROOM) {
mPrintf("Only mail is being networked at this node at the current time\n");
return;
}
if (!loggedIn || !logBuf.lbflags.NET_PRIVS) {
mPrintf("Sorry, you don't have net privileges.\n ");
return;
}
do {
getString("system to send to", sys, 20, TRUE, ECHO);
if (strLen(sys) == 0) return;
if (sys[0] == '?')
writeNet(FALSE);
else {
if (searchNameNet(sys) == ERROR)
mPrintf("No such system currently part of the net\n ");
else
notDone = FALSE;
}
} while (notDone);
getNet(searchNameNet(sys));
getArea(&cfg.codeBuf[cfg.nodeId], ourCode);
getArea(netBuf.netId, theirCode);
if (!cfg.longHaul && strCmp(ourCode, theirCode) != SAMESTRING) {
mPrintf("Sorry, local Citadels only, please.\n ");
return;
}
if (strCmp(ourCode, theirCode) != SAMESTRING && logBuf.credit == 0) {
mPrintf("Sorry, you have no credit for long distance net.\n ");
return;
}
strCpy(msgBuf.mbaddr, netBuf.netName);
makeMessage(FALSE, NULL, FALSE, TRUE);
}
/************************************************************************/
/* writeNet() write up nodes on the net. */
/************************************************************************/
writeNet(idsAlso)
char idsAlso;
{
int rover;
char *SystemBaud;
outFlag = OUTOK;
mPrintf("Systems on the net:\n ");
for (rover = 0; rover < cfg.netSize; rover++) {
getNet(rover);
if (netBuf.nbflags.in_use) {
switch (netBuf.baudCode) {
case ONLY_300: SystemBaud = "300"; break;
case BOTH_300_1200: SystemBaud = "300/1200"; break;
case TH_3_12_24: SystemBaud = "300/1200/2400"; break;
default: SystemBaud = "invalid!"; break;
}
mPrintf("%-22s", netBuf.netName);
if (idsAlso) mPrintf("%-22s%-16s%s", netBuf.netId,
(needToCall(rover)) ? "<need to call>" : "",
SystemBaud);
mPrintf("\n ");
}
}
}
/************************************************************************/
/* searchNameNet() Search net for given node name */
/************************************************************************/
searchNameNet(name)
label name;
{
int rover;
for (rover = 0; rover < cfg.netSize; rover++) {
if (netTab[rover].ntflags.in_use &&
hash(name) == netTab[rover].ntnmhash) {
getNet(rover);
if (strCmpU(netBuf.netName, name) == SAMESTRING)
return rover;
}
}
return ERROR;
}
/************************************************************************/
/* netStuff() Handles networking for the sysop */
/************************************************************************/
netStuff()
{
label who;
struct logBuffer lBuf;
int logNo;
do {
mPrintf("\n Net function: ");
switch (toUpper(iChar())) {
case 'R':
mPrintf("equest File\n ");
fileRequest();
break;
case 'X':
mPrintf("\bExit to main menu");
return;
case 'C':
mPrintf("redit setting\n ");
getNormStr("who", who, NAMESIZE, ECHO);
logNo = findPerson(who, &lBuf);
if (logNo == ERROR) {
mPrintf("No such person\n ");
break;
}
mPrintf("%s currently has %d credits.", who, lBuf.credit);
lBuf.credit = getNumber("How many now", 0, 255);
if (loggedIn && strCmpU(logBuf.lbname, who) == SAMESTRING)
logBuf.credit = lBuf.credit;
putLog(&lBuf, logNo);
break;
case 'V':
mPrintf("iew net list\n ");
writeNet(TRUE);
break;
case 'A':
mPrintf("dd node to net\n ");
addNetNode();
break;
case 'E':
mPrintf("dit a node\n ");
editNode();
break;
case 'N':
mPrintf("et privilege toggle\n ");
getNormStr("who", who, NAMESIZE, ECHO);
logNo = findPerson(who, &lBuf);
if (logNo == ERROR) {
mPrintf("No such person\n ");
break;
}
mPrintf(
"%s has %snet privileges\n ",
who,
(lBuf.lbflags.NET_PRIVS) ? "no " : ""
);
if (!getYesNo("Confirm")) break;
lBuf.lbflags.NET_PRIVS = !lBuf.lbflags.NET_PRIVS;
if (strCmpU(lBuf.lbname, logBuf.lbname) == SAMESTRING)
logBuf.lbflags.NET_PRIVS = lBuf.lbflags.NET_PRIVS;
putLog(&lBuf, logNo);
break;
case '?':
tutorial("netopt.mnu");
break;
default:
mPrintf(" ?\n ");
}
} while (1);
}
/************************************************************************/
/* addNetNode() Add a node to the net listing */
/************************************************************************/
addNetNode()
{
int searcher;
label temp;
getNormStr("System name", netBuf.netName, NAMESIZE, ECHO);
if (strLen(netBuf.netName) == 0) return;
getString("System ID", netBuf.netId, NAMESIZE, FALSE, ECHO);
if (strLen(netBuf.netId) == 0) return;
netBuf.baudCode =getNumber("Baud code (0=300, 1=300/1200, 2=300/1200/2400)",
0, 2);
netBuf.nbflags.in_use = TRUE;
netBuf.nbflags.normal_mail = FALSE;
netBuf.nbflags.room_files = FALSE;
for (searcher = 0; searcher < cfg.netSize; searcher++)
if (netTab[searcher].ntflags.in_use == FALSE) break;
if (searcher != cfg.netSize)
putNet(searcher);
else {
netTab =
(struct netTable *) realloc(netTab, sizeof (*netTab) * ++cfg.netSize);
searcher = cfg.netSize - 1;
putNet(searcher);
}
normId(netBuf.netId, temp);
netTab[searcher].ntnmhash = hash(netBuf.netName);
netTab[searcher].ntidhash = hash(temp);
}
/************************************************************************/
/* editNode() Edit a net node */
/************************************************************************/
editNode()
{
label sysname, temp;
int place;
getNormStr("Name of system to edit", sysname, NAMESIZE, ECHO);
if ((place = searchNameNet(sysname)) == ERROR) {
mPrintf("%s not listed!\n ", sysname);
return;
}
getNet(place);
while (1) {
mPrintf("\n (%s) edit fn: ", netBuf.netName);
switch (toUpper(iChar())) {
case 'X':
mPrintf("\bExit to net menu");
normId(netBuf.netId, temp);
netTab[place].ntnmhash = hash(netBuf.netName);
netTab[place].ntidhash = hash(temp);
netTab[place].ntflags.in_use = netBuf.nbflags.in_use;
putNet(place);
return;
case 'B':
mPrintf("aud code change\n ");
netBuf.baudCode =getNumber("Baud code (0=300, 1=300/1200, 2=300/1200/2400)",
0, 2);
break;
case 'N':
mPrintf("ame change\n ");
getNormStr("System name", netBuf.netName, NAMESIZE, ECHO);
break;
case 'I':
mPrintf("D change\n ");
getString("System ID", netBuf.netId, NAMESIZE, FALSE, ECHO);
break;
case 'K':
mPrintf("ill node from list\n ");
if (getYesNo("Confirm")) {
netBuf.nbflags.in_use = FALSE;
putNet(place);
sPrintf(temp, "a:%d.ml", thisNet);
temp[0] = cfg.netDisk + 'a';
unlink(temp);
return;
}
break;
case '?':
tutorial("netedit.mnu");
break;
default:
mPrintf("?\n ");
}
}
}
/************************************************************************/
/* inNetTime() Time to network? */
/************************************************************************/
inNetTime(hr, mn)
int hr, mn;
{
int thisHour, thisMin;
thisHour = cfg.netHour + (cfg.netLength / 60);
thisMin = cfg.netLength - ((thisHour - cfg.netHour) * 60);
if (hr < cfg.netHour) return FALSE;
if (hr > thisHour) return FALSE;
if (mn >= thisMin) return FALSE;
return TRUE;
}
/************************************************************************/
/* fileRequest() For network requests of files. */
/************************************************************************/
fileRequest()
{
struct fl_req file_data;
label system, dr, data;
char loc[100];
char abort, goodname;
FILE *temp, *fopen();
char *cd, *gcdir();
int place;
getNormStr("system to request file from", system, NAMESIZE, ECHO);
if (strLen(system) == 0) return;
if ((place = searchNameNet(system)) == ERROR) {
mPrintf("%s not listed!\n ", system);
return;
}
getNet(place);
sPrintf(loc, "name of room on %s that has desired file", system);
getNormStr(loc, file_data.room, NAMESIZE, ECHO);
if (strLen(file_data.room) == 0) return;
getNormStr("the file's name", file_data.roomfile, NAMESIZE, ECHO);
if (strLen(file_data.roomfile) == 0) return;
getString("what drive you want the file put on", dr, 2, FALSE, ECHO);
if (strLen(dr) == 0) return;
file_data.drive = dr[0];
mPrintf("Now we want to specify the exact directory on drive ");
mPrintf("%c to place the file in. ", toUpper(dr[0]));
mPrintf("Type the exact path, from the root.");
mPrintf(" If you want it in the root directory, then just type ");
mPrintf("Return. There is some error checking here, but not much.");
mPrintf(" '?' will abort.");
abort = FALSE;
setSpace(toUpper(dr[0]) - 'A', "");
cd = gcdir("");
good_path(file_data.path, 98);
if (file_data.path[1] != '?') {
chdir(file_data.path);
do {
getString("name the file will be stored under on this system",
file_data.filename, NAMESIZE, FALSE, ECHO);
if (strLen(file_data.filename) == 0) abort = TRUE;
else {
temp = fopen(file_data.filename, "r");
if (temp != NULL) {
fclose(temp);
mPrintf("'%s' already exists, and ", file_data.filename);
mPrintf("will be overwritten during networking.");
goodname = getYesNo("Is this what you want");
}
else goodname = TRUE;
}
} while (!abort && !goodname);
}
else abort = TRUE;
chdir(cd);
free(cd);
setSpace(cfg.homeDisk, "");
if (!abort) {
sPrintf(data, "a:%d.rfl", place);
data[0] = cfg.netDisk + 'a';
temp = fopen(data, "ab");
if (temp == NULL) {
mPrintf("Couldn't append to '%s'????", data);
}
fwrite(&file_data, sizeof (file_data), 1, temp);
fclose(temp);
netBuf.nbflags.room_files = TRUE;
putNet(place);
}
}